package com.lcx.security.schedule;

import com.lcx.security.FFmpegCommandManager.FFmpegManager;
import com.lcx.security.FFmpegCommandManager.FFmpegManagerImpl;
import com.lcx.security.config.StreamConfig;
import com.lcx.security.dao.TaskDaoImpl;
import com.lcx.security.entity.OutHandler;
import com.lcx.security.entity.TaskEntity;
import com.lcx.security.main.FFmpegCMD;
import com.lcx.security.myenum.StreamEnum;
import com.lcx.security.util.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Component
@EnableScheduling
public class ScheduleTask {
    protected static Logger logger = LoggerFactory.getLogger(ScheduleTask.class);
    // 每隔五分钟，检查一下视屏流转换状态
    @Scheduled(cron = "3 1/5 *  ? * *")
    public void checkVideoStream() throws InterruptedException {
        boolean checkIpPort = IpUtils.checkIpPort(StreamConfig.IP, StreamConfig.PORT);
        FFmpegManager fFmpegManager = new FFmpegManagerImpl();
        if (!checkIpPort){
            logger.info("要处理啊");
            fFmpegManager.stopAll();
        }
        // 当ip和端口连通的的时候，判断现在有没有执行 MP4-》hls，如果有则关闭
        else {
            logger.info("检查推流状态");
            TaskEntity query = fFmpegManager.query(StreamEnum.MP4_TO_HLS.getName());
            if (query != null && query.getProcess() != null){
                fFmpegManager.stopAll();

                restartPushStream();
            }

            // 如果没有则判断，当前运行的推流进程是否正常
            // 首先判断有无 rtsp -》 rtmp, 然后判断有无 rtmp-》 hls
            else{
                TaskEntity query1 = fFmpegManager.query(StreamEnum.RTSP_TO_RTMP.getName());
                // 如果 rtsp -》 rtmp 出现异常，则所有任务均需暂停重启
                if (checkTaskStatus(query1)){
                    fFmpegManager.stopAll();
                    restartPushStream();
                } else {
                    //  rtsp -》 rtmp 正常，则继续判断 rtmp-》 hls 是否正常
                    TaskEntity query2 = fFmpegManager.query(StreamEnum.RTMP_TO_HLS.getName());
                    if (checkTaskStatus(query2)) {
                        fFmpegManager.stop(query2.getId());
                        CompletableFuture.runAsync(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    FFmpegCMD.rtmpToHls();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                }
            }
        }
    }

    // 判断 TaskEntity 的工作状态 正常工作返回 false
    private boolean checkTaskStatus(TaskEntity taskEntity) {
        if (taskEntity == null || taskEntity.getProcess() == null || !taskEntity.getProcess().isAlive()){
            return true;
        }else {
            OutHandler thread = taskEntity.getThread();
            OutHandler thread1 = taskEntity.getThread1();
            if (thread == null || !thread.getDesstatus() ){
                if (thread1 == null || !thread.getDesstatus()){
                    return true;
                }
            }
            if (!thread.isAlive() && !thread1.isAlive()){
                return true;
            }
        }
        return false;
    }

    public static void restartPushStream() throws InterruptedException {
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                try {
                    FFmpegCMD.rtspToRtmp();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        Thread.sleep(5000);

        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                try {
                    FFmpegCMD.rtmpToHls();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Scheduled(cron = "0 0 0/2  ? * *")
    public void restart(){
        FFmpegManager fFmpegManager = new FFmpegManagerImpl();
        fFmpegManager.stopAll();
        try {
            restartPushStream();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
